﻿using Ibp.Service.Entity;
using Ibp.Service.Entity.DEntity;
using Ibp.Service.Entity.ODAEntity;
using OdaOperation.DB;
using System;
using System.Collections.Generic;
using System.Linq;
using Teigha.Core;
using Teigha.TD;

namespace OdaOperation.Utils
{
    public static class ExternalApi
    {
        // 将 DArc 对象转换为角度
        public static double DArcToAngle(this DArc od)
        {
            OdGePoint3d p = new OdGePoint3d(od.Center.X, od.Center.Y, 0.0);
            OdGePoint3d p2 = new OdGePoint3d(od.Start.X, od.Start.Y, 0.0);
            OdGePoint3d p3 = new OdGePoint3d(od.End.X, od.End.Y, 0.0);
            // 计算两个向量之间的夹角
            OdGeVector3d odGeVector3d = OdaWriteExtend.AngleTetweenVectors(p2, p);
            OdGeVector3d odGeVector3d2 = OdaWriteExtend.AngleTetweenVectors(p3, p);
            double num = (odGeVector3d.y > 0.0) ? OdaWriteExtend.AngleTetweenangleTo(odGeVector3d, OdGeVector3d.kXAxis) : (-OdaWriteExtend.AngleTetweenangleTo(odGeVector3d, OdGeVector3d.kXAxis));
            double num2 = (odGeVector3d2.y > 0.0) ? OdaWriteExtend.AngleTetweenangleTo(odGeVector3d2, OdGeVector3d.kXAxis) : (-OdaWriteExtend.AngleTetweenangleTo(odGeVector3d2, OdGeVector3d.kXAxis));
            double value;
            // 判断弧是顺时针还是逆时针
            if (od.IsClockWise)
            {
                value = num - num2;
            }
            else
            {
                value = num2 - num;
            }
            return OdaWriteExtend.RadianToAngle(Math.Abs(value));
        }

        // 将 DPolyline 对象转换为 DCurves 列表
        public static List<DCurve> DPolylineToDCurves(this DPolyline dpl, DbDatabase db = null, double precision = 0.0)
        {
            List<DCurve> list = new List<DCurve>();
            OdDbPolyline odDbPolyline = OdDbPolyline.createObject();
            // 将 DPolyline 中的顶点添加到 OdDbPolyline 对象中
            for (int i = 0; i < dpl.Vertexes.Count; i++)
            {
                odDbPolyline.addVertexAt(uint.Parse(i.ToString()), new OdGePoint2d(dpl.Vertexes[i].X, dpl.Vertexes[i].Y), dpl.Vertexes[i].Bulge);
            }
            // 如果 DPolyline 是闭合的，则添加首个顶点以闭合图形
            if (dpl.IsClose && dpl.Vertexes.Count > 2 && dpl.Vertexes.FirstOrDefault().Distance(dpl.Vertexes.LastOrDefault()) > 0.1)
            {
                odDbPolyline.addVertexAt(uint.Parse(dpl.Vertexes.Count.ToString()), new OdGePoint2d(dpl.Vertexes.First<DVertex>().X, dpl.Vertexes.First<DVertex>().Y), dpl.Vertexes.First<DVertex>().Bulge);
            }
            // 分解 OdDbPolyline 对象为 OdRxObjectPtrArray
            OdRxObjectPtrArray odRxObjectPtrArray = new OdRxObjectPtrArray();
            odDbPolyline.explode(odRxObjectPtrArray);
            // 遍历 OdRxObjectPtrArray 中的对象
            for (int j = 0; j < odRxObjectPtrArray.Count; j++)
            {
                OdRxObject odRxObject = odRxObjectPtrArray[j];
                OdDbArc odDbArc = odRxObject as OdDbArc;
                // 如果对象是圆弧，则创建 DArc 对象并添加到列表中
                if (odDbArc != null)
                {
                    DArc dArc = new DArc();
                    dArc.IsClockWise = false;
                    OdGePoint3d odGePoint3d = new OdGePoint3d();
                    odDbArc.getStartPoint(odGePoint3d);
                    OdGePoint3d odGePoint3d2 = new OdGePoint3d();
                    odDbArc.getEndPoint(odGePoint3d2);
                    dArc.Start = new DPoint(odGePoint3d.x, odGePoint3d.y, odGePoint3d.z);
                    dArc.End = new DPoint(odGePoint3d2.x, odGePoint3d2.y, odGePoint3d2.z);
                    dArc.Center = new DPoint(odDbArc.center().x, odDbArc.center().y, odDbArc.center().z);
                    dArc.LineWidth = dpl.LineWidth;
                    dArc.LineTypeId = dpl.LineTypeId;
                    dArc.LineColor = dpl.LineColor;
                    dArc.Layer = dpl.Layer;
                    dArc.LayerId = dpl.LayerId;
                    dArc.BlockId = dpl.BlockId;
                    list.Add(dArc);
                }
                OdDbLine odDbLine = odRxObject as OdDbLine;
                // 如果对象是直线，则创建 DLine 对象并添加到列表中
                if (odDbLine != null)
                {
                    list.Add(new DLine
                    {
                        Start = new DPoint(odDbLine.startPoint().x, odDbLine.startPoint().y, odDbLine.startPoint().z),
                        End = new DPoint(odDbLine.endPoint().x, odDbLine.endPoint().y, odDbLine.endPoint().z),
                        LineWidth = dpl.LineWidth,
                        LineTypeId = dpl.LineTypeId,
                        LineColor = dpl.LineColor,
                        Layer = dpl.Layer,
                        LayerId = dpl.LayerId,
                        BlockId = dpl.BlockId
                    });
                }
            }
            return list;
        }

        // 将 DCurves 列表转换为 DPolyline 对象
        public static DPolyline DCurveslineToDPoly(List<DCurve> dcurves, bool isClose = false)
        {
            if (dcurves.Count <= 0)
            {
                throw new Exception("集合中没有值");
            }
            DPolyline dPolyline = new DPolyline();
            dPolyline.IsClose = isClose;
            List<DVertex> list = new List<DVertex>();
            dPolyline.Vertexes = list;
            for (int i = 0; i < dcurves.Count; i++)
            {
                DArc dArc = dcurves[i] as DArc;
                // 如果是 DArc 对象，则将其转换为 DVertex 对象并添加到列表中
                if (dArc != null)
                {
                    list.Add(new DVertex
                    {
                        X = dArc.Start.X,
                        Y = dArc.Start.Y,
                        IsClockWise = dArc.IsClockWise,
                        Bulge = dArc.DArcToAngle()
                    });
                    if (i == dcurves.Count - 1)
                    {
                        list.Add(new DVertex
                        {
                            X = dArc.End.X,
                            Y = dArc.End.Y
                        });
                    }
                }
                else
                {
                    DLine dLine = dcurves[i] as DLine;
                    // 如果是 DLine 对象，则将其转换为 DVertex 对象并添加到列表中
                    if (dLine != null)
                    {
                        list.Add(new DVertex
                        {
                            X = dLine.Start.X,
                            Y = dLine.Start.Y
                        });
                        if (i == dcurves.Count - 1)
                        {
                            list.Add(new DVertex
                            {
                                X = dLine.End.X,
                                Y = dLine.End.Y
                            });
                        }
                    }
                }
            }
            return dPolyline;
        }

        // 判断两个 double 类型的值是否相等
        public static bool DEqualOda(this double a, double b, double precision = 3.2808398950131236E-08)
        {
            return Math.Abs(a - b) < precision;
        }
    }

}
